/******************************************************************
 * @version      : 1.0
 * @Author       : zhl
 * @Date         : 2023-06-19 14:49:20
 * @LastEditors  : zhl
 * @E-Mail       : zhll168@163.com
 * @Description  : 业务描述
 ******************************************************************/
#include <thread>
#include <iostream>
#include <string.h>
#include <strings.h>

#include "CLogger.h"
#include "upgrade.h"
#include "JsonManager.h"
#include "upgrade_data.h"
#include "CommandManager.h"

#define RESULT_LEN 2048
#define DEVICE_TO_CLOUD_TOPIC(sn) "d2c/"+sn+"/command/default/v1"


CommandManager* CommandManager::c_instance = NULL;
bool CommandManager::c_is_singleton = false;

CommandManager::CommandManager(/* args */){
    c_is_singleton = false;
    c_mm == nullptr;
}

CommandManager::~CommandManager(){
}
//此处线程风险
CommandManager* CommandManager::getInstance(){
    c_is_singleton = true;
    if(NULL == c_instance){
        c_instance = new CommandManager();
    }
    return c_instance;
}

void CommandManager::init(std::shared_ptr<CMosquittoManager> mm, char *sn){
    c_mm = mm;
    if(NULL == sn){
        c_sn = "0000000000000000";
    } else {
        c_sn = sn;
    }
}

std::string CommandManager::execute(char *cmd){
    
    if((NULL == cmd) || (1 > strlen(cmd))){
        return "命令为空";
    }
    std::string ret = "";
    static char *result = (char *)malloc(RESULT_LEN);
    bzero(result, RESULT_LEN);
    FILE *fp = NULL; 
    fp=popen(cmd, "r"); 
    if(NULL == fp){
        return "命令执行失败";
    }
    while(NULL != fgets(result, RESULT_LEN,fp)){
        ret.append(result);
    } 
    pclose(fp);
    return ret;
}

std::string CommandManager::get_cmd_result_report_data(std::string &result, int64_t req_id){
    EXECUTE_CMD_RESULT cmd_ret;
    cmd_ret.command = "CMD_EXECUTE_COMMAND";
    cmd_ret.command_id = req_id;
    cmd_ret.command_type = "REP";
    cmd_ret.sn = c_sn;
    cmd_ret.timestamp = get_timestamp();
    cmd_ret.data.result = result;
    std::string tmp_content =JsonManager::getInstance().get_cmd_result(cmd_ret);
    return tmp_content;
}

void CommandManager::cmd_execute_thread(CommandManager *cm, std::string cmd, int64_t req_id){
    if(NULL == cm){
        return ;
    }
    //
    std::string ret = cm->execute((char *)cmd.c_str());
    ret = cm->get_cmd_result_report_data(ret, req_id);
    std::string topic = DEVICE_TO_CLOUD_TOPIC(cm->c_sn);
    CLogger::getInstance()->log_i("%s命令结果: %s", cmd.c_str(), ret.c_str());
    if(nullptr != cm->c_mm){
        cm->c_mm->publish(topic.c_str(), ret.length(), (const void *)ret.c_str());
    }
}

void CommandManager::exec_cmd(std::string cmd, int64_t req_id){
    std::thread cmd_Thread(cmd_execute_thread, this, cmd, req_id);
    if(c_is_singleton){
        cmd_Thread.detach();
    } else {
        cmd_Thread.join();
    }
}